﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MyCalc
{
    public partial class Form1 : Form
    {   
        //声明变量，分别代表输入的第一个数字，第二个数字，结果和操作符,特别注意_num1也可以用于缓存前一次的计算结果
        private decimal _num1 = 0, _num2 = 0, _result = 0;
        private string _operator = "";
        //声明操作符的个数，用于区分是否是首个操作符
        private int _operatorCount = 0;
        //运算数的位数用于区分输入是否是组成一个新的数，中间结果会显示在编辑框，但此时运算数位数是0输入数不会添加在编辑框后面而是先清空再输入
        private int _numCount = 0;
        //类字段，进制编码
        private string _numCode = "dec";
        //十进制转二进制
        public string DecToBin(int dec) { 
            //获取十进制的绝对值
            int abs_dec = Math.Abs(dec);
            //转二进制
            string bin = "";
            while (abs_dec >= 2) {
                bin = Convert.ToChar(abs_dec % 2 + '0') + bin;
                abs_dec /= 2;
            }
            bin = Convert.ToChar(abs_dec + '0') + bin;
            if (dec >= 0)
                return bin;
            else
                return "-" + bin;
        }
        //二进制转十进制
        public int BinToDec(string bin) { 
            //获取首位字符判断正负
            string firstChar = bin.Substring(0, 1);
            //获取二进制绝对值
            string abs_bin = bin;
            if (firstChar == "-")
                abs_bin = bin.Substring(1, bin.Length - 1);
            int dec = 0;
            for (int i = abs_bin.Length; i >= 1; i--) {
                dec = dec + Convert.ToInt32(abs_bin[i - 1] - '0') * (int)(Math.Pow(2, abs_bin.Length - i));
            }
            if (firstChar == "-")
                return -dec;
            else
                return dec;
        }
        //十进制转八进制
        public string DecToOct(int dec) { 
            //获取十进制的绝对值
            int abs_dec = Math.Abs(dec);
            string oct = "";
            while (abs_dec >= 8) {
                oct = Convert.ToChar(abs_dec % 8 + '0') + oct;
                abs_dec /= 8;
            }
            oct = Convert.ToChar(abs_dec + '0') + oct;
            if (dec >= 0)
                return oct;
            else
                return "-" + oct;
        }
        //八转十进制
        public int OctToDec(String oct){
            //获取首位字符判断正负
            string firstChar = oct.Substring(0, 1);
            //获取八进制绝对值
            string abs_oct = oct;
            if (firstChar == "-")
                abs_oct = oct.Substring(1, oct.Length - 1);
            int dec = 0;
            for (int i = abs_oct.Length; i >= 1; i--) {
                dec = dec + Convert.ToInt32(abs_oct[i - 1] - '0') * (int)(Math.Pow(8, abs_oct.Length - i));
            }
            if (firstChar == "-")
                return -dec;
            else
                return dec;
        }
        public Form1()
        {
            InitializeComponent();
        }
        //点击数字按钮1
        private void buttonNum1_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "1";
        }
        //点击数字按钮2
        private void buttonNum2_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "2";
        }
        //点击数字按钮3
        private void buttonNum3_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "3";
        }
        //点击数字按钮4
        private void buttonNum4_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "4";
        }
        //点击数字按钮5
        private void buttonNum5_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "5";
        }
        //点击数字按钮6
        private void buttonNum6_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "6";
        }
        //点击数字按钮7
        private void buttonNum7_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "7";
        }
        //点击数字按钮8
        private void buttonNum8_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "8";
        }
        //点击数字按钮9
        private void buttonNum9_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "9";
        }
        //点击数字按钮0
        private void buttonNum0_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            textBoxResult.Text = textBoxResult.Text + "0";
        }
        //点击按钮.
        private void buttonDot_Click(object sender, EventArgs e)
        {
            //运算数位数+1
            _numCount++;
            if (_numCount == 1)
                textBoxResult.Clear();
            //当前没有.才把.加入
            if (textBoxResult.Text.IndexOf('.') == -1) 
                textBoxResult.Text = textBoxResult.Text + ".";
        }

        //点击按钮+
        private void buttonAdd_Click(object sender, EventArgs e)
        {   
            //操作符数量+1
            _operatorCount++;
            //后面输入的是新数字，运算数位数归0，虽然显示中间结果，但是输入后判断为输入新的数字，先清空编辑框
            _numCount = 0;
            //该操作符是第一个操作符
            if (_operatorCount == 1)
            {
                //保存第一个数字
                if (_numCode == "dec")
                    _num1 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBoxResult.Text);
                //记录操作符
                _operator = "+";
                //显示框清空
                textBoxResult.Text = "";
            }
            //该次操作不是第一次操作，先计算该次操作前表达式的值保存在_num1中
            else {
                if (_numCode == "dec")
                    _num2 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num2 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num2 = OctToDec(textBoxResult.Text);
                //注意此时的操作符还未更新不是最新的而是前一次的
                if (_operator == "+") {
                    _num1 += _num2;
                }else if (_operator == "-") {
                    _num1 -= _num2;
                }else if (_operator == "*") {
                    _num1 *= _num2;
                }else if(_operator == "/"){
                    _num1 /= _num2;
                }
                _operator = "+";
                //显示中间结果
                //结果转为对应进制
                if (_numCode == "dec")
                    textBoxResult.Text = _num1.ToString();
                else if (_numCode == "bin")
                    textBoxResult.Text = DecToBin((int)Math.Round(_num1));
                else if (_numCode == "oct")
                    textBoxResult.Text = DecToOct((int)Math.Round(_num1));
            }
        }

        //点击按钮-
        private void buttonSubtract_Click(object sender, EventArgs e)
        {
            //操作符数量+1
            _operatorCount++;
            //后面输入的是新数字，运算数位数归0，虽然显示中间结果，但是输入后判断为输入新的数字，先清空编辑框
            _numCount = 0;
            //该操作符是第一个操作符
            if (_operatorCount == 1)
            {
                //保存第一个数字
                if (_numCode == "dec")
                    _num1 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBoxResult.Text);
                //记录操作符
                _operator = "-";
                //显示框清空
                textBoxResult.Text = "";
            }
            //该次操作不是第一次操作，先计算该次操作前表达式的值保存在_num1中
            else
            {
                if (_numCode == "dec")
                    _num2 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num2 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num2 = OctToDec(textBoxResult.Text);
                //z注意此时的操作符还未更新不是最新的而是前一次的
                if (_operator == "+")
                {
                    _num1 += _num2;
                }
                else if (_operator == "-")
                {
                    _num1 -= _num2;
                }
                else if (_operator == "*")
                {
                    _num1 *= _num2;
                }
                else if (_operator == "/")
                {
                    _num1 /= _num2;
                }
                _operator = "-";
                //显示中间结果
                //结果转为对应进制
                if (_numCode == "dec")
                    textBoxResult.Text = _num1.ToString();
                else if (_numCode == "bin")
                    textBoxResult.Text = DecToBin((int)Math.Round(_num1));
                else if (_numCode == "oct")
                    textBoxResult.Text = DecToOct((int)Math.Round(_num1));
            }
        }

        //点击按钮*
        private void buttonMultiply_Click(object sender, EventArgs e)
        {
            //操作符数量+1
            _operatorCount++;
            //后面输入的是新数字，运算数位数归0，虽然显示中间结果，但是输入后判断为输入新的数字，先清空编辑框
            _numCount = 0;
            //该操作符是第一个操作符
            if (_operatorCount == 1)
            {
                //保存第一个数字,以十进制存储
                if (_numCode == "dec")
                    _num1 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBoxResult.Text);
                //记录操作符
                _operator = "*";
                //显示框清空
                textBoxResult.Text = "";
            }
            //该次操作不是第一次操作，先计算该次操作前表达式的值保存在_num1中
            else
            {
                if (_numCode == "dec")
                    _num2 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num2 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num2 = OctToDec(textBoxResult.Text);
                //注意此时的操作符还未更新不是最新的而是前一次的
                if (_operator == "+")
                {
                    _num1 += _num2;
                }
                else if (_operator == "-")
                {
                    _num1 -= _num2;
                }
                else if (_operator == "*")
                {
                    _num1 *= _num2;
                }
                else if (_operator == "/")
                {
                    _num1 /= _num2;
                }
                _operator = "*";
                //显示中间结果
                //结果转为对应进制
                if (_numCode == "dec")
                    textBoxResult.Text = _num1.ToString();
                else if (_numCode == "bin")
                    textBoxResult.Text = DecToBin((int)Math.Round(_num1));
                else if (_numCode == "oct")
                    textBoxResult.Text = DecToOct((int)Math.Round(_num1));
            }
        }
        //点击按钮/
        private void buttonDivide_Click(object sender, EventArgs e)
        {
            //操作符数量+1
            _operatorCount++;
            //后面输入的是新数字，运算数位数归0，虽然显示中间结果，但是输入后判断为输入新的数字，先清空编辑框
            _numCount = 0;
            //该操作符是第一个操作符
            if (_operatorCount == 1)
            {
                //保存第一个数字,以十进制存储
                if (_numCode == "dec")
                    _num1 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num1 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num1 = OctToDec(textBoxResult.Text);
                //记录操作符
                _operator = "/";
                //显示框清空
                textBoxResult.Text = "";
            }
            //该次操作不是第一次操作，先计算该次操作前表达式的值保存在_num1中
            else
            {
                if (_numCode == "dec")
                    _num2 = Convert.ToDecimal(textBoxResult.Text);
                else if (_numCode == "bin")
                    _num2 = BinToDec(textBoxResult.Text);
                else if (_numCode == "oct")
                    _num2 = OctToDec(textBoxResult.Text);
                //z注意此时的操作符还未更新不是最新的而是前一次的
                if (_operator == "+")
                {
                    _num1 += _num2;
                }
                else if (_operator == "-")
                {
                    _num1 -= _num2;
                }
                else if (_operator == "*")
                {
                    _num1 *= _num2;
                }
                else if (_operator == "/")
                {
                    _num1 /= _num2;
                }
                _operator = "/";
                //显示中间结果
                //结果转为对应进制
                if (_numCode == "dec")
                    textBoxResult.Text = _num1.ToString();
                else if (_numCode == "bin")
                    textBoxResult.Text = DecToBin((int)Math.Round(_num1));
                else if (_numCode == "oct")
                    textBoxResult.Text = DecToOct((int)Math.Round(_num1));
            }
        }
        //点击按钮=
        private void buttonEqual_Click(object sender, EventArgs e)
        {
            //读取内容赋值给_num2
            if (_numCode == "dec")
                _num2 = Convert.ToDecimal(textBoxResult.Text);
            else if (_numCode == "bin")
                _num2 = BinToDec(textBoxResult.Text);
            else if (_numCode == "oct")
                _num2 = OctToDec(textBoxResult.Text);
            //根据操作符进行运算
            if (_operator == "+") {
                _result = _num1 + _num2;
            }else if(_operator == "-"){
                _result = _num1 - _num2;    
            }else if(_operator == "*"){
                _result = _num1 * _num2;
            }else if(_operator == "/"){
                _result = _num1 / _num2;
            }
            //显示结果
            //结果转为对应进制
            if (_numCode == "dec")
                textBoxResult.Text = _result.ToString();
            else if (_numCode == "bin")
                textBoxResult.Text = DecToBin((int)Math.Round(_result));
            else if (_numCode == "oct")
                textBoxResult.Text = DecToOct((int)Math.Round(_result));
            //操作符数量归0
            _operatorCount = 0;
            //下一轮输入的是新数字或操作符，运算数位数归0，为下一次运算做准备
            _numCount = 0;
        }
        //点击按钮<-
        private void buttonBackSpace_Click(object sender, EventArgs e)
        {
            //编辑框不为空
            if (textBoxResult.Text.Length > 0) { 
                //使用substring截取
                textBoxResult.Text = textBoxResult.Text.Substring(0, textBoxResult.Text.Length - 1);
            }
            //如果编辑框为空或者字符号默认为0
            if (textBoxResult.Text == "" || textBoxResult.Text == "+" || textBoxResult.Text == "-")
                textBoxResult.Text = "0";
        }
        //点击按钮+/-
        private void buttonSign_Click(object sender, EventArgs e)
        {
            //保证不为空
            if (textBoxResult.Text.Length > 0) { 
                //截取运算数的第一位
                string firstChar = textBoxResult.Text.Substring(0, 1);
                if (firstChar == "+") {
                    textBoxResult.Text = "-" + textBoxResult.Text.Substring(1, textBoxResult.Text.Length);
                }
                else if (firstChar == "-") {
                    textBoxResult.Text = "+" + textBoxResult.Text.Substring(1, textBoxResult.Text.Length);
                }else{
                    textBoxResult.Text = "-" + textBoxResult.Text.Substring(0, textBoxResult.Text.Length);
                }
            }
        }
        //点击c按钮，清除所有
        private void buttonClear_Click(object sender, EventArgs e)
        {
            //初始化所有变量
            _num1 = 0; _num2 = 0; _result = 0;
            _operator = "";
            _operatorCount = 0;
            _numCount = 0;
            //清空编辑框
            textBoxResult.Text = "0";
        }

        private void textBoxResult_TextChanged(object sender, EventArgs e)
        {

        }
        //键盘响应事件
        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            //根据输入的值来模拟点击事件
            if (e.KeyChar == '0')
                buttonNum0.PerformClick();
            else if (e.KeyChar == '1')
                buttonNum1.PerformClick();
            else if (e.KeyChar == '2')
                buttonNum2.PerformClick();
            else if (e.KeyChar == '3')
                buttonNum3.PerformClick();
            else if (e.KeyChar == '4')
                buttonNum4.PerformClick();
            else if (e.KeyChar == '5')
                buttonNum5.PerformClick();
            else if (e.KeyChar == '6')
                buttonNum6.PerformClick();
            else if (e.KeyChar == '7')
                buttonNum7.PerformClick();
            else if (e.KeyChar == '8')
                buttonNum8.PerformClick();
            else if (e.KeyChar == '9')
                buttonNum9.PerformClick();
            else if (e.KeyChar == '.')
                buttonDot.PerformClick();
            else if (e.KeyChar == '+')
                buttonAdd.PerformClick();
            else if (e.KeyChar == '-')
                buttonSubtract.PerformClick();
            else if (e.KeyChar == '*')
                buttonMultiply.PerformClick();
            else if (e.KeyChar == '/')
                buttonDivide.PerformClick();
            else if (e.KeyChar == '=')
                buttonEqual.PerformClick();
            else if (e.KeyChar == (char)Keys.Back)//Keys是一个枚举类型，其变量对应键盘输入
                buttonBackSpace.PerformClick();
            //光标落在编辑框行尾
            textBoxResult.Select(textBoxResult.Text.Length, 0); //激活空间选择文本框的范围，第一个参数是start，第二个是length
        }

        private void radioButtonDecimal_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonDecimal.Checked == true) {
                //只有.补全为0.0
                if (textBoxResult.Text == ".")
                    textBoxResult.Text = "0.0";
                //非空则进行进制转化
                if (textBoxResult.Text != "") { 
                    //原来是二进制
                    if (_numCode == "bin") {
                        textBoxResult.Text = BinToDec(textBoxResult.Text).ToString();
                    }
                    else if (_numCode == "oct") {
                        textBoxResult.Text = OctToDec(textBoxResult.Text).ToString();
                    }
                }
            }
            buttonNum2.Enabled = true;
            buttonNum3.Enabled = true;
            buttonNum4.Enabled = true;
            buttonNum5.Enabled = true;
            buttonNum6.Enabled = true;
            buttonNum7.Enabled = true;
            buttonNum8.Enabled = true;
            buttonNum9.Enabled = true;
            buttonDot.Enabled = true;
            //保存进制编码
            _numCode = "dec";
        }

        private void radioButtonOctal_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonOctal.Checked == true)
            {
                //只有.补全为0.0
                if (textBoxResult.Text == ".")
                    textBoxResult.Text = "0.0";
                //非空则进行进制转化
                if (textBoxResult.Text != "")
                {
                    //原来是十进制
                    if (_numCode == "dec")
                    {
                        textBoxResult.Text = DecToOct((int)Math.Round(Convert.ToDecimal(textBoxResult.Text)));
                    }
                    else if (_numCode == "bin")
                    {
                        int dec = BinToDec(textBoxResult.Text);
                        textBoxResult.Text = DecToOct(dec);
                    }
                }
            }
            buttonNum2.Enabled = true;
            buttonNum3.Enabled = true;
            buttonNum4.Enabled = true;
            buttonNum5.Enabled = true;
            buttonNum6.Enabled = true;
            buttonNum7.Enabled = true;
            buttonNum8.Enabled = false;
            buttonNum9.Enabled = false;
            buttonDot.Enabled = false;
            //保存进制编码
            _numCode = "oct";
        }

        private void radioButtonBinary_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonBinary.Checked == true)
            {
                //只有.补全为0.0
                if (textBoxResult.Text == ".")
                    textBoxResult.Text = "0.0";
                //非空则进行进制转化
                if (textBoxResult.Text != "")
                {
                    //原来是十进制
                    if (_numCode == "dec")
                    {
                        textBoxResult.Text = DecToBin((int)Math.Round(Convert.ToDecimal(textBoxResult.Text)));
                    }
                    else if (_numCode == "oct")
                    {
                        int dec = OctToDec(textBoxResult.Text);
                        textBoxResult.Text = DecToBin(dec);
                    }
                }
            }
            buttonNum2.Enabled = false;
            buttonNum3.Enabled = false;
            buttonNum4.Enabled = false;
            buttonNum5.Enabled = false;
            buttonNum6.Enabled = false;
            buttonNum7.Enabled = false;
            buttonNum8.Enabled = false;
            buttonNum9.Enabled = false;
            buttonDot.Enabled = false;
            //保存进制编码
            _numCode = "bin";
        }
        
    }
}
